package com.dmgis.hndz.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dmgis.entity.*;
import com.dmgis.hndz.pojoVo.Zhaa11aVO;
import com.dmgis.hndz.service.*;
import com.dmgis.hndz.common.utils.DmgisUtils;
import com.dmgis.hndz.common.utils.DocxUtil;
import com.dmgis.hndz.common.utils.LayerUtil;
import com.dmgis.hndz.mapper.*;
import com.dmgis.hndz.pojo.*;
import com.dmgis.service.DmServiceConnector;
import com.dmgis.service.MapXML;
import com.dmgis.weblib.MapCommon;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.QueryMapper;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.servlet.http.HttpSession;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Slf4j
@Service
public class YjfwServiceImpl implements YjfwService {

    @Value("${dmgis.ip}")
    private String dmgisIp;

    @Value("${dmgis.port}")
    private String dmgisPort;

    @Value("${dmgis.serveName}")
    private String serveName;

    @Value("${city}")
    private String cityName;

    @Value("${filePath.active}")
    private String active;

    @Autowired
    private EmergencyPointMapper emergencyPointMapper;
    @Autowired
    private DangerSourceService dangerSourceService;

    @Autowired
    private ImpGoalService impGoalService;

    @Autowired
    private BaseProductService baseProductService;

    @Qualifier("mongoPrimaryTemplate")
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private EmergencyMapper emergencyMapper;

    @Autowired
    private PotentialPointsMapper potentialPointsMapper;

    @Autowired
    private WaterLoggingPointInfoMapper waterLoggingPointInfoMapper;

    @Autowired
    private FireHistoryMapper fireHistoryMapper;

    @Autowired
    private Jcca16aMapper jcca16aMapper;

    @Autowired
    private Qxca01aMapper qxca01aMapper;

    @Autowired
    private Zhaa11aMapper zhaa11aMapper;


    @Autowired
    private RiskManagementService riskManagementService;

    @Override
    public List<LayerCountryDto> getCountryName(String name) throws UnsupportedEncodingException {
        DmServiceConnector conn = new DmServiceConnector(dmgisIp, dmgisPort);
        String xml = "";
        //属性服务
        DmFeatureMapService dmFeatureMapService = new DmFeatureMapService();
        dmFeatureMapService.setStrLayerName("镇点");
        DmFeatureParam dmFeatureParam = new DmFeatureParam();
        dmFeatureParam.setAttribute(1);
        dmFeatureParam.setGeometry(1);
        dmFeatureParam.setFeatureLimit(0);
//        dmFeatureParam.setEnvelop(1);
        dmFeatureMapService.setParam(dmFeatureParam);
        dmFeatureMapService.setType("0");
        DmSql dmSql = new DmSql();
        dmSql.setStrSql("dmgis_id > 0");
        dmFeatureMapService.setM_sql(dmSql);
        xml = dmFeatureMapService.getXmlString();
        String res = conn.getServiceXml(serveName, 2, xml);
        MapXML mapXML = new MapXML();
        DmGetFeature feature = mapXML.dmGetFeatureInfo(res);
        List<DmObj> map = feature.getObjset();
        List<LayerCountryDto> layerCountryDtos = new ArrayList<>();
        for (DmObj obj : map) {
            LayerCountryDto layerCountryDto = new LayerCountryDto();
            List<DmRcoVal> rec = obj.getRec();
            String rcoName = "";
            for (DmRcoVal dmRcoVal : rec) {
                if (dmRcoVal.getFldName().equals("NAME")) {
                    rcoName = dmRcoVal.getFldVal();
                    break;
                }
            }
            if (rcoName.contains(name)) {
                layerCountryDto.setName(rcoName);
                String strPnt = obj.getStrPnt();
                String[] pntArr = strPnt.split(" ");
              //  DmMapPoint dmMapPoint = lbtToWgs(Double.parseDouble(pntArr[0]), Double.parseDouble(pntArr[1]));
                layerCountryDto.setLon(String.valueOf(Double.parseDouble(pntArr[0])));
                layerCountryDto.setLat(String.valueOf(Double.parseDouble(pntArr[1])));
                layerCountryDtos.add(layerCountryDto);
            }
        }
        return layerCountryDtos;
    }

    @Override
    public List<EmergencyPoint> listPointByName(String name) {
        return emergencyPointMapper.selectList(Wrappers.<EmergencyPoint>lambdaQuery().like(EmergencyPoint::getName, name));
    }

    public static double dmsToLl(String dms) {
        double ds = Double.parseDouble(dms);
        if (ds > 180) {
            int dd = (int) (ds / 10000);
            int ff = (int) ((ds - dd * 10000) / 100);
            int mm = (int) (ds - dd * 10000 - ff * 100);
            ds = dd + ff / 60.00 + mm / 3600.00;
        }
        return ds;
    }
    @Override
    public List<LayerRcoDto> listLayerByScope(DlfxDto dlfxDto,String xzbm) throws UnsupportedEncodingException, NoSuchFieldException, InstantiationException, IllegalAccessException {
//        if (dlfxDto.getLayerName().equals(""))
        StringBuilder sb = new StringBuilder();
        for (List<Double> po : dlfxDto.getPos()) {
            //DmMapPoint dmMapPoint = DmgisUtils.wgsToLbt(po.get(0), po.get(1));
            sb.append(po.get(0)).append(" ").append(po.get(1)).append(";");
        }
        sb.deleteCharAt(sb.length() - 1);

        if (dlfxDto.getLayerName().equals("隐患点") ||
                dlfxDto.getLayerName().equals("危险源") ||
                dlfxDto.getLayerName().equals("重要目标") ||
                dlfxDto.getLayerName().equals("易涝点") ||
                dlfxDto.getLayerName().equals("历史火点")||
                dlfxDto.getLayerName().equals("监测点")||
                dlfxDto.getLayerName().equals("实况站点")
        ) {
            List<LayerRcoDto> layerRcoDtos = new ArrayList<>();
            switch (dlfxDto.getLayerName()) {
                case "隐患点":
                    QueryWrapper<Zhaa11A> PotentialPointsqueryWrapper = new QueryWrapper<>();
                    PotentialPointsqueryWrapper.likeRight("zhaa11a012",xzbm);
                    List<Zhaa11A> list = zhaa11aMapper.selectList(PotentialPointsqueryWrapper);
                    City city = new City();
                    city.setAnum(5000);
                    city.setCity("4312");
                    city.setDivcode(xzbm);
                    HttpSession session = null;
                    List<?> res = riskManagementService.queryZhcxZhd(city, session);


                    for (Zhaa11A zhaa11a: list) {
                       if (zhaa11a.getZhaa11a050()!=null&&!zhaa11a.getZhaa11a050().equals("")&&zhaa11a.getZhaa11a052()!=null&&!zhaa11a.getZhaa11a052().equals("")){
                           MapPoint mapPoint = new MapPoint();
                           mapPoint.setLon(Double.parseDouble(zhaa11a.getZhaa11a050()));
                           mapPoint.setLat(Double.parseDouble(zhaa11a.getZhaa11a052()));

                           if (DmgisUtils.isScope(mapPoint, dlfxDto.getPos())) {
                               LayerRcoDto layerRcoDto = new LayerRcoDto();
                               Zhaa11aVO zhaa11Avo = new Zhaa11aVO();
                               zhaa11Avo.setZhaa11a050(zhaa11a.getZhaa11a050());
                               zhaa11Avo.setZhaa11a052(zhaa11a.getZhaa11a052());
                               for (Object object : res){
                                   JSONObject jsonObject = (JSONObject)object;
                                   jsonObject.get("id");
                                 if (jsonObject.get("id").equals(zhaa11a.getZhaa11a012())){
                                     layerRcoDto.setRcoValObject(object);
                                 }
                               }

                               layerRcoDto.setLon(Double.parseDouble(zhaa11a.getZhaa11a050()));
                               layerRcoDto.setLat(Double.parseDouble(zhaa11a.getZhaa11a052()));
                               layerRcoDto.setObjectClass(EmergencyDisaster.class);
                               layerRcoDto.setPos(new double[][]{{Double.parseDouble(zhaa11a.getZhaa11a050()), Double.parseDouble(zhaa11a.getZhaa11a052())}});
                               layerRcoDtos.add(layerRcoDto);
                           }
                       }

                    }
                    break;
                case "危险源":
                    List<DangerSource> list1 = dangerSourceService.list();
                    for (DangerSource dangerSource : list1) {
                        MapPoint mapPoint = new MapPoint(dangerSource.getLon(), dangerSource.getLat());
                        if (DmgisUtils.isScope(mapPoint, dlfxDto.getPos())) {
                            LayerRcoDto layerRcoDto = new LayerRcoDto();
                            layerRcoDto.setRcoValObject(dangerSource);
                            layerRcoDto.setLon(dangerSource.getLon());
                            layerRcoDto.setLat(dangerSource.getLat());
                            layerRcoDto.setObjectClass(DangerSource.class);
                            layerRcoDto.setPos(new double[][]{{dangerSource.getLon(), dangerSource.getLat()}});
                            layerRcoDtos.add(layerRcoDto);
                        }
                    }
                    break;
                case "重要目标":
                    List<ImpGoal> list2 = impGoalService.getList1();
                    for (ImpGoal impGoal : list2) {
                        MapPoint mapPoint = new MapPoint(impGoal.getLon(), impGoal.getLat());
                        if (DmgisUtils.isScope(mapPoint, dlfxDto.getPos())) {
                            LayerRcoDto layerRcoDto = new LayerRcoDto();
                            layerRcoDto.setRcoValObject(impGoal);
                            layerRcoDto.setLon(impGoal.getLon());
                            layerRcoDto.setLat(impGoal.getLat());
                            layerRcoDto.setObjectClass(ImpGoal.class);
                            layerRcoDto.setPos(new double[][]{{impGoal.getLon(), impGoal.getLat()}});
                            layerRcoDtos.add(layerRcoDto);
                        }
                    }
                    break;
                case "易涝点":
                    List<WaterLoggingPointInfo> list3 = waterLoggingPointInfoMapper.selectList(null);
                    for (WaterLoggingPointInfo waterLoggingPointInfo : list3) {
                        MapPoint mapPoint = new MapPoint(waterLoggingPointInfo.getLon(), waterLoggingPointInfo.getLat());
                        if (DmgisUtils.isScope(mapPoint, dlfxDto.getPos())) {
                            LayerRcoDto layerRcoDto = new LayerRcoDto();
                            layerRcoDto.setRcoValObject(waterLoggingPointInfo);
                            layerRcoDto.setLon(waterLoggingPointInfo.getLon());
                            layerRcoDto.setLat(waterLoggingPointInfo.getLat());
                            layerRcoDto.setObjectClass(ImpGoal.class);
                            layerRcoDto.setPos(new double[][]{{waterLoggingPointInfo.getLon(), waterLoggingPointInfo.getLat()}});
                            layerRcoDtos.add(layerRcoDto);
                        }
                    }
                    break;
                case "历史火点":
                    QueryWrapper<FireHistory> FireHistoryqueryWrapper = new QueryWrapper<>();
                    List<FireHistory> list4 = fireHistoryMapper.selectList(null);
                    for (FireHistory fireHistory : list4) {
                        MapPoint mapPoint = new MapPoint(fireHistory.getLongitude(), fireHistory.getLatitude());
                        if (DmgisUtils.isScope(mapPoint, dlfxDto.getPos())) {
                            LayerRcoDto layerRcoDto = new LayerRcoDto();
                            layerRcoDto.setRcoValObject(fireHistory);
                            layerRcoDto.setLon(fireHistory.getLongitude());
                            layerRcoDto.setLat(fireHistory.getLatitude());
                            layerRcoDto.setObjectClass(ImpGoal.class);
                            layerRcoDto.setPos(new double[][]{{fireHistory.getLongitude(), fireHistory.getLatitude()}});
                            layerRcoDtos.add(layerRcoDto);
                        }
                    }
                    break;
                case "监测点":
                    QueryWrapper<Jcca16a> Jcca16aqueryWrapper = new QueryWrapper<>();
                    Jcca16aqueryWrapper.likeRight("jcca16a170",xzbm);
                    List<Jcca16a> list5 =jcca16aMapper.selectList(Jcca16aqueryWrapper);
                    for (Jcca16a jcca16a : list5) {
                        if (jcca16a.getJcca16a070()!=null&&!jcca16a.getJcca16a070().equals("")){
                            if (jcca16a.getJcca16a080()!=null&&!jcca16a.getJcca16a080().equals("")){
                                MapPoint mapPoint = new MapPoint();
                                mapPoint.setLon( jcca16a.getJcca16a080().doubleValue());//x
                                mapPoint.setLat(jcca16a.getJcca16a070().doubleValue());//y
                                if (DmgisUtils.isScope(mapPoint, dlfxDto.getPos())) {
                                    LayerRcoDto layerRcoDto = new LayerRcoDto();
                                    layerRcoDto.setRcoValObject(jcca16a);
                                    layerRcoDto.setLon(jcca16a.getJcca16a080().doubleValue());
                                    layerRcoDto.setLat(jcca16a.getJcca16a070().doubleValue());
                                    layerRcoDto.setObjectClass(ImpGoal.class);
                                    layerRcoDto.setPos(new double[][]{{jcca16a.getJcca16a080().doubleValue(), jcca16a.getJcca16a070().doubleValue()}});
                                    layerRcoDtos.add(layerRcoDto);
                                }
                            }
                        }
                    }
                    break;
                case "实况站点":
                    QueryWrapper<Qxca01a> qxca01aqueryWrapper = new QueryWrapper<>();
                    qxca01aqueryWrapper.eq("qxca01a040","怀化市");
                    List<Qxca01a> list6 =qxca01aMapper.selectList(qxca01aqueryWrapper);
                    for (Qxca01a qxca01a : list6) {
                        Double lon = dmsToLl(qxca01a.getQxca01a060().toString());
                        Double lat =  dmsToLl(qxca01a.getQxca01a070().toString());
                        MapPoint mapPoint = new MapPoint(lon, lat);
                        if (DmgisUtils.isScope(mapPoint, dlfxDto.getPos())) {
                            LayerRcoDto layerRcoDto = new LayerRcoDto();
                            layerRcoDto.setRcoValObject(qxca01a);
                            layerRcoDto.setLon(lon);
                            layerRcoDto.setLat(lat);
                            layerRcoDto.setObjectClass(ImpGoal.class);
                            layerRcoDto.setPos(new double[][]{{lon, lat}});
                            layerRcoDtos.add(layerRcoDto);
                        }
                    }
                    break;


            }

            return layerRcoDtos;
        }

        DmServiceConnector conn = new DmServiceConnector(dmgisIp, dmgisPort);
        String xml = "";
        //属性服务
        DmFeatureMapService dmFeatureMapService = new DmFeatureMapService();
        dmFeatureMapService.setStrLayerName(dlfxDto.getLayerName());
        DmFeatureParam dmFeatureParam = new DmFeatureParam();
        dmFeatureParam.setAttribute(1);
        dmFeatureParam.setGeometry(1);
        dmFeatureParam.setFeatureLimit(0);
        dmFeatureMapService.setParam(dmFeatureParam);
        dmFeatureMapService.setType("0");
        DmSql dmSql = new DmSql();
        dmSql.setStrPos(sb.toString());
        dmFeatureMapService.setM_sql(dmSql);
        xml = dmFeatureMapService.getXmlString();
        System.out.println(xml);
        String res = conn.getServiceXml(serveName, 2, xml);
//        System.err.println(res);
        List<LayerRcoDto> layerRcoDtos = new ArrayList<>();
        if (dlfxDto.getLayerName().equals("灾害点")
                || dlfxDto.getLayerName().equals("村点")
                )
        {
            //点转换
            List<Dopxml> locations = parseXMLdop(res);

            for (Dopxml obj : locations) {
                //  List<DmRcoVal> rec = obj.getRec();
                LayerRcoDto layerRcoDto = new LayerRcoDto();
                layerRcoDto.setDopxml(obj);
//            Object layerObject = getLayerObject(rec, dlfxDto.getLayerName());
                Class objectClass = LayerUtil.getLayerClass(dlfxDto.getLayerName());
                layerRcoDto.setRcoValObject(Dopxml.class); //属性
                layerRcoDto.setObjectClass(objectClass);//对应的实体class
                String strPnt = obj.getPnt();
                if (strPnt == null) {
                    strPnt = obj.getCor();
                    String[] pnts = strPnt.split(";");
                    List<DmMapPoint> points = new ArrayList<>();
                    for (String pnt : pnts) {
                        String[] point = pnt.split(" ");
                        DmMapPoint dmMapPoint = new DmMapPoint(Double.parseDouble(point[0]), Double.parseDouble(point[1]));
                        points.add(dmMapPoint);
                    }


                    if (dlfxDto.getLayerName().equals("铁路") || dlfxDto.getLayerName().equals("国道") || dlfxDto.getLayerName().equals("省道") || dlfxDto.getLayerName().equals("高速") || dlfxDto.getLayerName().equals("县道") || dlfxDto.getLayerName().equals("乡村道路")) {
                        //线图层
                        //获取外接矩形
                        DmMapRectangle rectMinMax = MapCommon.getRectMinMax(points);
                        //获取外接矩形中心点
                        DmMapPoint rectCenter = MapCommon.getRectCenter(rectMinMax);

                        //    DmMapPoint dmMapPoint = lbtToWgs(rectCenter.getX(), rectCenter.getY());
                        layerRcoDto.setLon(rectCenter.getX());
                        layerRcoDto.setLat(rectCenter.getY());
                    } else {
                        //面图层
                        int[] nParts = {points.size()};
                        MapCommon mapCommon = new MapCommon();
                        DmMapPoint polygonCenterPoint = mapCommon.getPolygonCenterPoint(points.toArray(new DmMapPoint[0]), nParts, 1);
                        // DmMapPoint dmMapPoint = lbtToWgs(polygonCenterPoint.getX(), polygonCenterPoint.getY());
                        layerRcoDto.setLon(polygonCenterPoint.getX());
                        layerRcoDto.setLat(polygonCenterPoint.getY());
                    }
                    //设置实体点集
                    double[][] pos = new double[points.size()][2];
                    for (int i = 0; i < points.size(); i++) {
                        //        DmMapPoint dmMapPoint = lbtToWgs(points.get(i).getX(), points.get(i).getY());
                        pos[i][0] = points.get(i).getX();
                        pos[i][1] = points.get(i).getY();
                    }
                    layerRcoDto.setPos(pos);
                } else {
                    //点图层
                    String[] point = strPnt.split(" ");
//                DmMapPoint dmMapPoint = lbtToWgs(Double.parseDouble(point[0]), Double.parseDouble(point[1]));
                    layerRcoDto.setLon(Double.parseDouble(point[0]));
                    layerRcoDto.setLat(Double.parseDouble(point[1]));
                    double[][] pos = new double[1][2];
                    pos[0][0] = Double.parseDouble(point[0]);
                    pos[0][1] =Double.parseDouble(point[1]);
                    layerRcoDto.setPos(pos);
                }
                layerRcoDtos.add(layerRcoDto);
            }

        }
        if (dlfxDto.getLayerName().equals("水系"))
        {
            //面转换
            List<Location> locations = parseXMLArea(res);
        }
        if (dlfxDto.getLayerName().equals("铁路")
                || dlfxDto.getLayerName().equals("国道")
                || dlfxDto.getLayerName().equals("省道")
                || dlfxDto.getLayerName().equals("高速")
                || dlfxDto.getLayerName().equals("县道")
                || dlfxDto.getLayerName().equals("乡村道路"))
        {
            //线转换
            List<Dopxml> locations = parseXMLdop(res);
        }


        return layerRcoDtos;
    }

    @Override
    public List<LayerRcoDto> listLayerByScopeList(MultiplePosDlfxDto multiplePosDlfxDto) throws UnsupportedEncodingException, NoSuchFieldException, InstantiationException, IllegalAccessException {
        StringBuilder sb = new StringBuilder();
        String layerName = multiplePosDlfxDto.getLayerName();
        List<List<List<Double>>> posList = multiplePosDlfxDto.getPosList();
        for (List<List<Double>> pos  : posList) {
            for (List<Double> po : pos) {
                DmMapPoint dmMapPoint = DmgisUtils.wgsToLbt(po.get(0), po.get(1));
                sb.append(dmMapPoint.getX()).append(" ").append(dmMapPoint.getY()).append(";");
            }
            sb.deleteCharAt(sb.length() - 1);
            sb.append("*");
        }
        sb.deleteCharAt(sb.length() - 1);


        if (layerName.equals("灾害点") ||
                layerName.equals("危险源") ||
                layerName.equals("重要目标") ||
                layerName.equals("易涝点") ||
                layerName.equals("历史火点")) {
            List<LayerRcoDto> layerRcoDtos = new ArrayList<>();
            switch (layerName) {
                case "灾害点":
                    List<PotentialPoints> list = potentialPointsMapper.selectList(null);
                    for (PotentialPoints potentialPoints : list) {
                        MapPoint mapPoint = new MapPoint(potentialPoints.getLon(), potentialPoints.getLat());
                        for (List<List<Double>> pos : posList) {
                            if (DmgisUtils.isScope(mapPoint, pos)){
                                LayerRcoDto layerRcoDto = new LayerRcoDto();
                                layerRcoDto.setRcoValObject(potentialPoints);
                                layerRcoDto.setLon(potentialPoints.getLon());
                                layerRcoDto.setLat(potentialPoints.getLat());
                                layerRcoDto.setObjectClass(EmergencyDisaster.class);
                                layerRcoDto.setPos(new double[][]{{potentialPoints.getLon(), potentialPoints.getLat()}});
                                layerRcoDtos.add(layerRcoDto);
                            }
                        }
                    }
                    break;
                case "危险源":
                    List<DangerSource> list1 = dangerSourceService.list();
                    for (DangerSource dangerSource : list1) {
                        MapPoint mapPoint = new MapPoint(dangerSource.getLon(), dangerSource.getLat());
                        for (List<List<Double>> pos : posList) {
                            if (DmgisUtils.isScope(mapPoint, pos)){
                                LayerRcoDto layerRcoDto = new LayerRcoDto();
                                layerRcoDto.setRcoValObject(dangerSource);
                                layerRcoDto.setLon(dangerSource.getLon());
                                layerRcoDto.setLat(dangerSource.getLat());
                                layerRcoDto.setObjectClass(DangerSource.class);
                                layerRcoDto.setPos(new double[][]{{dangerSource.getLon(), dangerSource.getLat()}});
                                layerRcoDtos.add(layerRcoDto);
                            }
                        }
                    }
                    break;
                case "重要目标":
                    List<ImpGoal> list2 = impGoalService.getList1();
                    for (ImpGoal impGoal : list2) {
                        MapPoint mapPoint = new MapPoint(impGoal.getLon(), impGoal.getLat());
                        for (List<List<Double>> pos : posList) {
                            if (DmgisUtils.isScope(mapPoint, pos)){
                                LayerRcoDto layerRcoDto = new LayerRcoDto();
                                layerRcoDto.setRcoValObject(impGoal);
                                layerRcoDto.setLon(impGoal.getLon());
                                layerRcoDto.setLat(impGoal.getLat());
                                layerRcoDto.setObjectClass(ImpGoal.class);
                                layerRcoDto.setPos(new double[][]{{impGoal.getLon(), impGoal.getLat()}});
                                layerRcoDtos.add(layerRcoDto);
                            }
                        }
                    }
                    break;
                case "易涝点":
                    List<WaterLoggingPointInfo> list3 = waterLoggingPointInfoMapper.selectList(null);
                    for (WaterLoggingPointInfo waterLoggingPointInfo : list3) {
                        MapPoint mapPoint = new MapPoint(waterLoggingPointInfo.getLon(), waterLoggingPointInfo.getLat());
                        for (List<List<Double>> pos : posList) {
                            if (DmgisUtils.isScope(mapPoint, pos)){
                                LayerRcoDto layerRcoDto = new LayerRcoDto();
                                layerRcoDto.setRcoValObject(waterLoggingPointInfo);
                                layerRcoDto.setLon(waterLoggingPointInfo.getLon());
                                layerRcoDto.setLat(waterLoggingPointInfo.getLat());
                                layerRcoDto.setObjectClass(ImpGoal.class);
                                layerRcoDto.setPos(new double[][]{{waterLoggingPointInfo.getLon(), waterLoggingPointInfo.getLat()}});
                                layerRcoDtos.add(layerRcoDto);
                            }
                        }
                    }
                    break;
                case "历史火点":
                    List<FireHistory> list4 = fireHistoryMapper.selectList(null);
                    for (FireHistory fireHistory : list4) {
                        MapPoint mapPoint = new MapPoint(fireHistory.getLongitude(), fireHistory.getLatitude());
                        for (List<List<Double>> pos : posList) {
                            if (DmgisUtils.isScope(mapPoint, pos)){
                                LayerRcoDto layerRcoDto = new LayerRcoDto();
                                layerRcoDto.setRcoValObject(fireHistory);
                                layerRcoDto.setLon(fireHistory.getLongitude());
                                layerRcoDto.setLat(fireHistory.getLatitude());
                                layerRcoDto.setObjectClass(ImpGoal.class);
                                layerRcoDto.setPos(new double[][]{{fireHistory.getLongitude(), fireHistory.getLatitude()}});
                                layerRcoDtos.add(layerRcoDto);
                            }
                        }
                    }
                    break;
            }

            return layerRcoDtos;
        }

        DmServiceConnector conn = new DmServiceConnector(dmgisIp, dmgisPort);
        String xml = "";
        //属性服务
        DmFeatureMapService dmFeatureMapService = new DmFeatureMapService();
        dmFeatureMapService.setStrLayerName(layerName);
        DmFeatureParam dmFeatureParam = new DmFeatureParam();
        dmFeatureParam.setAttribute(1);
        dmFeatureParam.setGeometry(1);
        dmFeatureParam.setFeatureLimit(0);
        dmFeatureMapService.setParam(dmFeatureParam);
        dmFeatureMapService.setType("0");
        DmSql dmSql = new DmSql();
        dmSql.setStrPos(sb.toString());
        dmFeatureMapService.setM_sql(dmSql);
        xml = dmFeatureMapService.getXmlString();
        System.out.println(xml);
        String res = conn.getServiceXml(serveName, 2, xml);
//        System.err.println(res);
        MapXML mapXML = new MapXML();
        DmGetFeature feature = mapXML.dmGetFeatureInfo(res);
        List<DmObj> map = feature.getObjset();
        List<LayerRcoDto> layerRcoDtos = new ArrayList<>();
        for (DmObj obj : map) {
            List<DmRcoVal> rec = obj.getRec();
            LayerRcoDto layerRcoDto = new LayerRcoDto();
            Object layerObject = getLayerObject(rec, layerName);
            Class objectClass = LayerUtil.getLayerClass(layerName);
            layerRcoDto.setRcoValObject(layerObject);
            layerRcoDto.setObjectClass(objectClass);
            String strPnt = obj.getStrPnt();
            if (strPnt == null) {
                strPnt = obj.getStrCor();
                String[] pnts = strPnt.split(";");
                List<DmMapPoint> points = new ArrayList<>();
                for (String pnt : pnts) {
                    String[] point = pnt.split(" ");
                    DmMapPoint dmMapPoint = new DmMapPoint(Double.parseDouble(point[0]), Double.parseDouble(point[1]));
                    points.add(dmMapPoint);
                }


                if (layerName.equals("铁路") || layerName.equals("国道") || layerName.equals("省道") || layerName.equals("高速") || layerName.equals("县道") || layerName.equals("乡村道路")) {
                    //线图层
                    //获取外接矩形
                    DmMapRectangle rectMinMax = MapCommon.getRectMinMax(points);
                    //获取外接矩形中心点
                    DmMapPoint rectCenter = MapCommon.getRectCenter(rectMinMax);

                   // DmMapPoint dmMapPoint = lbtToWgs(rectCenter.getX(), rectCenter.getY());
                    layerRcoDto.setLon(rectCenter.getX());
                    layerRcoDto.setLat(rectCenter.getY());
                } else {
                    //面图层
                    int[] nParts = {points.size()};
                    MapCommon mapCommon = new MapCommon();
                    DmMapPoint polygonCenterPoint = mapCommon.getPolygonCenterPoint(points.toArray(new DmMapPoint[0]), nParts, 1);
                  //  DmMapPoint dmMapPoint = lbtToWgs(polygonCenterPoint.getX(), polygonCenterPoint.getY());
                    layerRcoDto.setLon(polygonCenterPoint.getX());
                    layerRcoDto.setLat(polygonCenterPoint.getY());
                }
                //设置实体点集
                double[][] pos = new double[points.size()][2];
                for (int i = 0; i < points.size(); i++) {
                  //  DmMapPoint dmMapPoint = lbtToWgs(points.get(i).getX(), points.get(i).getY());
                    pos[i][0] = points.get(i).getX();
                    pos[i][1] = points.get(i).getY();
                }
                layerRcoDto.setPos(pos);
            } else {
                //点图层
                String[] point = strPnt.split(" ");
              //  DmMapPoint dmMapPoint = lbtToWgs(Double.parseDouble(point[0]), Double.parseDouble(point[1]));
                layerRcoDto.setLon(Double.parseDouble(point[0]));
                layerRcoDto.setLat(Double.parseDouble(point[1]));
                double[][] pos = new double[1][2];
                pos[0][0] =Double.parseDouble(point[0]);
                pos[0][1] = Double.parseDouble(point[1]);
                layerRcoDto.setPos(pos);
            }
            layerRcoDtos.add(layerRcoDto);
        }
        return layerRcoDtos;
    }

    @Override
    public Object createProduct(Integer year, String issueNum, String userName, String phone, String title, String type, String skName, String skData, String ybData, String dlData, String layerName, MultipartFile[] images, Date date) {
        //模板路径
        String templatePath;
        //产品路径
        String targetPath;

        ApplicationHome applicationHome = new ApplicationHome(this.getClass());
        if (active.equals("dev")) {
            templatePath = applicationHome.getDir().getParentFile().getParentFile().getAbsolutePath() +
                    "\\src\\main\\resources\\templates\\yjfwTemp\\应急文档模板.docx";
            targetPath = applicationHome.getDir().getParentFile().getParentFile().getAbsolutePath() +
                    "\\src\\main\\resources\\temp\\应急文档.docx";
        } else {
            templatePath = applicationHome.getSource().getParentFile() +
                    "\\resource\\templates\\yjfwTemp\\应急文档模板.docx";
            targetPath = applicationHome.getSource().getParentFile() +
                    "\\resources\\temp\\应急文档.docx";
        }

        try (
                //申请资源
                FileInputStream templateStream = new FileInputStream(templatePath);
//                InputStream templateStream = new ClassPathResource(templatePath).getInputStream();
                XWPFDocument document = new XWPFDocument(templateStream);
                FileOutputStream targetSteam = new FileOutputStream(targetPath);
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            //段落替换
            String[] placeholders = new String[]{"[年份]", "[期数]", "[签发人]", "[标题]", "[应急的类型]"};
            //替换内容
            String[] replacements = new String[]{String.valueOf(year), issueNum, userName, title, type};

            List<XWPFParagraph> paragraphs = document.getParagraphs();
            // 替换段落内容
            for (int i = 0; i < paragraphs.size(); i++) {
                XWPFParagraph paragraph = paragraphs.get(i);
                //获取段落内容
                String text = paragraph.getText();

                //替换文字内容
                DocxUtil.replaceTextInParagraph(paragraph, placeholders, replacements);

                //插入图片
                if (text.equals("[图片]")) {
                    //获取下标
                    XmlCursor cursor = paragraph.getCTP().newCursor();
                    XWPFParagraph newPara = document.insertNewParagraph(cursor);
                    newPara.setAlignment(ParagraphAlignment.CENTER);//居中
                    XWPFRun newParaRun = newPara.createRun();
                    for (MultipartFile image : images) {
                        //插入图片
                        newParaRun.addPicture(image.getInputStream(), XWPFDocument.PICTURE_TYPE_PNG, "image.png,", Units.toEMU(420), Units.toEMU(270));
                    }
                    document.removeBodyElement(document.getPosOfParagraph(paragraph));
                }
                //插入实况数据表格
                if (StringUtils.isNotBlank(skData) && text.equals("[实况分析]")) {
                    //json字符串转换为对象列表
                    List<MsgMediumSmallScale> skList = JSON.parseArray(skData, MsgMediumSmallScale.class);
                    //获取下标
                    XmlCursor cursor = paragraph.getCTP().newCursor();
                    XWPFTable table = document.insertNewTbl(cursor);
                    //添加表头
                    XWPFTableRow row_0 = table.getRow(0);
                    row_0.getCell(0).setText("站点编号");
                    row_0.addNewTableCell().setText("站点名称");
                    row_0.addNewTableCell().setText(skName);
                    skList.forEach(sk -> {
                        XWPFTableRow dataRow = table.createRow();
                        dataRow.getCell(0).setText(sk.getStationid());
                        dataRow.getCell(1).setText(sk.getStationname());
                        switch (skName) {
                            case "降水":
                                dataRow.getCell(2).setText(String.valueOf(sk.getRain()));
                                break;
                            case "空气温度":
                                dataRow.getCell(2).setText(String.valueOf(sk.getDrybulbtemp()));
                                break;
                            case "最高气温":
                                dataRow.getCell(2).setText(String.valueOf(sk.getMaxtemp()));
                                break;
                            case "最低气温":
                                dataRow.getCell(2).setText(String.valueOf(sk.getMintemp()));
                                break;
                            case "10分钟风向":
                                dataRow.getCell(2).setText(String.valueOf(sk.getWindd10ms()));
                                break;
                            case "最大风向":
                                dataRow.getCell(2).setText(String.valueOf(sk.getMaxwindd()));
                                break;
                            case "最大风速":
                                dataRow.getCell(2).setText(String.valueOf(sk.getMaxwindv()));
                                break;
                            case "本站气压":
                                dataRow.getCell(2).setText(String.valueOf(sk.getStationpress()));
                                break;
                        }
                    });
                    setTableLocation(table, "center");
                    setCellLocation(table, "CENTER", "center");
                    document.removeBodyElement(document.getPosOfParagraph(paragraph));
                }
                //插入预报数据表格
                if (StringUtils.isNotBlank(ybData) && text.equals("[预报分析]")) {
                    //json字符串转换为对象列表
                    List<TownshipForecast> ybList = JSON.parseArray(ybData, TownshipForecast.class);
                    //获取下标
                    XmlCursor cursor = paragraph.getCTP().newCursor();
                    XWPFTable table = document.insertNewTbl(cursor);
                    //添加表头
                    XWPFTableRow row_0 = table.getRow(0);
                    row_0.getCell(0).setText("站点编号");
                    row_0.addNewTableCell().setText("站点名称");
                    row_0.addNewTableCell().setText("天气现象");
                    row_0.addNewTableCell().setText("雨量");
                    row_0.addNewTableCell().setText("最高气温");
                    row_0.addNewTableCell().setText("最低气温");
                    row_0.addNewTableCell().setText("风速");
                    row_0.addNewTableCell().setText("风向");
                    row_0.addNewTableCell().setText("县区");
                    //设置数据
                    ybList.forEach(yb -> {
                        XWPFTableRow dataRow = table.createRow();
                        dataRow.getCell(0).setText(yb.getStationid());
                        dataRow.getCell(1).setText(yb.getStationname());
                        dataRow.getCell(2).setText(yb.getWeather1());
                        dataRow.getCell(3).setText(String.valueOf(yb.getRain()));
                        dataRow.getCell(4).setText(String.valueOf(yb.getMaxtemp()));
                        dataRow.getCell(5).setText(String.valueOf(yb.getMintemp()));
                        dataRow.getCell(6).setText(String.valueOf(yb.getWinds()));
                        dataRow.getCell(7).setText(String.valueOf(yb.getWindd()));
                        dataRow.getCell(8).setText(String.valueOf(yb.getAreaname()));
                    });
                    setTableLocation(table, "center");
                    setCellLocation(table, "CENTER", "center");
                    document.removeBodyElement(document.getPosOfParagraph(paragraph));
                }
                //插入地理分析数据表格
                if (StringUtils.isNotBlank(dlData) && StringUtils.isNotBlank(layerName) && text.equals("[地理分析]")) {
                    //获取下标
                    XmlCursor cursor = paragraph.getCTP().newCursor();
                    XWPFTable table = document.insertNewTbl(cursor);
                    XWPFTableRow row_0 = table.getRow(0);
                    Class objectClass = null;
                    switch (layerName) {
                        case "村点":
                            objectClass = VillagePointLayer.class;
                            System.out.println(dlData);
                            //json字符串转换为对象列表
                            List<VillagePointLayer> dlList = JSON.parseArray(dlData, objectClass);

                            //添加表头

                            row_0.getCell(0).setText("村名");
                            row_0.addNewTableCell().setText("村长");
                            row_0.addNewTableCell().setText("联系电话");
                            row_0.addNewTableCell().setText("人口数量");
                            //设置数据
                            if (dlList!=null){
                                dlList.forEach(dl -> {
                                    System.out.println(dl);
                                    XWPFTableRow dataRow = table.createRow();
                                    dataRow.getCell(0).setText(dl.getNAME());

                                });
                            }
                            break;
                        case "乡镇面":
                            //添加表头
                            row_0.getCell(0).setText("乡镇名称");
                            row_0.addNewTableCell().setText("镇长");
                            row_0.addNewTableCell().setText("联系电话");
                            row_0.addNewTableCell().setText("人口数量");
                            break;
                    }

                    setTableLocation(table, "center");
                    setCellLocation(table, "CENTER", "center");
                    document.removeBodyElement(document.getPosOfParagraph(paragraph));
                }
            }
            // 将生成的文档保存到输出文件
            document.write(targetSteam);
            log.info("文档生成成功");
            targetSteam.close();

            // 设置前端响应
            byte[] buffer = new byte[1024];
            int bytesRead;
            FileInputStream inputStream = new FileInputStream(targetPath);
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, bytesRead);
            }
            byte[] byteArray = byteArrayOutputStream.toByteArray();
            //查询是否入库

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH");
            String productName = sdf.format(date) + title + type;
            List<Emergency> emergencieList = emergencyMapper.selectList(Wrappers.<Emergency>lambdaQuery()
                    .eq(Emergency::getDocpath, productName));
            if (emergencieList.size()>0){
                emergencyMapper.delete(Wrappers.<Emergency>lambdaQuery()
                        .eq(Emergency::getDocpath, productName));
                List<BaseProduct> baseProductList = baseProductService.getList2(productName, "应急服务");
                baseProductList.forEach(i->{
                    mongoTemplate.remove(Query.query(new Criteria().and("id").is(i.getId()).and("table_name").is("base_product")),HyDocFile.class);
                });
                baseProductService.deleteByProductName(productName);
            }
            String maxId = emergencyMapper.getMaxId();
            if (maxId==null){
                maxId = "1";
            }
            Emergency emergency = new Emergency();
            emergency.setId(Integer.valueOf(maxId));
            emergency.setDocpath(productName);
            emergencyMapper.updateById(emergency);

            List<BaseProduct> list2 = baseProductService.getList2(productName, "应急服务");
            if (list2.size() != 0) {
                //pg已入库，存入mongo库
                HyDocFile hyDocFile = new HyDocFile();
                hyDocFile.setData(byteArray);
                hyDocFile.setTable_name("base_product");
                hyDocFile.setId(String.valueOf(list2.get(0)));
                mongoTemplate.save(hyDocFile);
            } else {
                //先存入pg库
                BaseProduct baseProduct = new BaseProduct();
                baseProduct.setForecasttime(date);
                baseProduct.setMaketime(date);
                baseProduct.setMaker(userName);
                baseProduct.setContext(cityName + sdf.format(date) + "发布最新应急产品：" + title);
                baseProduct.setProductname(productName);
                baseProduct.setProducttype("应急服务");
                baseProductService.save(baseProduct);
                //存入mongo库
                HyDocFile hyDocFile = new HyDocFile();
                hyDocFile.setData(byteArray);
                hyDocFile.setTable_name("base_product");
                hyDocFile.setId(String.valueOf(baseProduct.getId()));
                mongoTemplate.save(hyDocFile);
            }
            HttpHeaders headers = new HttpHeaders();
            headers.setContentDispositionFormData("attachment", productName + "应急文档.docx");
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentLength(byteArray.length);
//            wordToPdf(targetPath,targetPdfPath);
            return new ResponseEntity<>(byteArray, headers, HttpStatus.OK);

        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("文档生成失败");
        }
        return null;
    }

    @Override
    public Object insertData(String resourcePath, String targetPath, String skName, String skData, String ybData, String dlData, String layerName, MultipartFile[] images) {
        try (
                //申请资源
                InputStream templateStream = new ClassPathResource(resourcePath).getInputStream(); XWPFDocument document = new XWPFDocument(templateStream); FileOutputStream targetSteam = new FileOutputStream(targetPath); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();) {

            List<XWPFParagraph> paragraphs = document.getParagraphs();
            //替换段落内容
            for (int i = 0; i < paragraphs.size(); i++) {
                XWPFParagraph paragraph = paragraphs.get(i);
                //获取段落内容
                String text = paragraph.getText();
                //插入图片
                if (text.equals("[图片]")) {
                    //获取下标
                    XmlCursor cursor = paragraph.getCTP().newCursor();
                    XWPFParagraph newPara = document.insertNewParagraph(cursor);
                    newPara.setAlignment(ParagraphAlignment.CENTER);//居中
                    XWPFRun newParaRun = newPara.createRun();
                    for (MultipartFile image : images) {
                        //插入图片
                        newParaRun.addPicture(image.getInputStream(), XWPFDocument.PICTURE_TYPE_PNG, "image.png,", Units.toEMU(300), Units.toEMU(250));
                    }
                    document.removeBodyElement(document.getPosOfParagraph(paragraph));
                }
                //插入实况数据表格
                if (StringUtils.isNotBlank(skData) && text.equals("[实况分析]")) {
                    //json字符串转换为对象列表
                    List<MsgMediumSmallScale> skList = JSON.parseArray(skData, MsgMediumSmallScale.class);
                    //获取下标
                    XmlCursor cursor = paragraph.getCTP().newCursor();
                    XWPFTable table = document.insertNewTbl(cursor);
                    //添加表头
                    XWPFTableRow row_0 = table.getRow(0);
                    row_0.getCell(0).setText("站点编号");
                    row_0.addNewTableCell().setText("站点名称");
                    row_0.addNewTableCell().setText(skName);
                    skList.forEach(sk -> {
                        XWPFTableRow dataRow = table.createRow();
                        dataRow.getCell(0).setText(sk.getStationid());
                        dataRow.getCell(1).setText(sk.getStationname());
                        switch (skName) {
                            case "降水":
                                dataRow.getCell(2).setText(String.valueOf(sk.getRain()));
                                break;
                            case "空气温度":
                                dataRow.getCell(2).setText(String.valueOf(sk.getDrybulbtemp()));
                                break;
                            case "最高气温":
                                dataRow.getCell(2).setText(String.valueOf(sk.getMaxtemp()));
                                break;
                            case "最低气温":
                                dataRow.getCell(2).setText(String.valueOf(sk.getMintemp()));
                                break;
                            case "10分钟风向":
                                dataRow.getCell(2).setText(String.valueOf(sk.getWindd10ms()));
                                break;
                            case "最大风向":
                                dataRow.getCell(2).setText(String.valueOf(sk.getMaxwindd()));
                                break;
                            case "最大风速":
                                dataRow.getCell(2).setText(String.valueOf(sk.getMaxwindv()));
                                break;
                            case "本站气压":
                                dataRow.getCell(2).setText(String.valueOf(sk.getStationpress()));
                                break;
                        }
                    });
                    setTableLocation(table, "center");
                    setCellLocation(table, "CENTER", "center");
                    document.removeBodyElement(document.getPosOfParagraph(paragraph));
                }
                //插入预报数据表格
                if (StringUtils.isNotBlank(ybData) && text.equals("[预报分析]")) {
                    //json字符串转换为对象列表
                    List<TownshipForecast> ybList = JSON.parseArray(ybData, TownshipForecast.class);
                    //获取下标
                    XmlCursor cursor = paragraph.getCTP().newCursor();
                    XWPFTable table = document.insertNewTbl(cursor);
                    //添加表头
                    XWPFTableRow row_0 = table.getRow(0);
                    row_0.getCell(0).setText("站点编号");
                    row_0.addNewTableCell().setText("站点名称");
                    row_0.addNewTableCell().setText("天气现象");
                    row_0.addNewTableCell().setText("最高气温");
                    row_0.addNewTableCell().setText("最低气温");
                    row_0.addNewTableCell().setText("风速");
                    row_0.addNewTableCell().setText("风向");
                    row_0.addNewTableCell().setText("县区");
                    //设置数据
                    ybList.forEach(yb -> {
                        XWPFTableRow dataRow = table.createRow();
                        dataRow.getCell(0).setText(yb.getStationid());
                        dataRow.getCell(1).setText(yb.getStationname());
                        dataRow.getCell(2).setText(yb.getWeather1());
                        dataRow.getCell(3).setText(String.valueOf(yb.getMaxtemp()));
                        dataRow.getCell(4).setText(String.valueOf(yb.getMintemp()));
                        dataRow.getCell(5).setText(String.valueOf(yb.getWinds()));
                        dataRow.getCell(6).setText(String.valueOf(yb.getWindd()));
                        dataRow.getCell(7).setText(String.valueOf(yb.getAreaname()));
                    });
                    setTableLocation(table, "center");
                    setCellLocation(table, "CENTER", "center");
                    document.removeBodyElement(document.getPosOfParagraph(paragraph));
                }
                //插入地理分析数据表格
                if (StringUtils.isNotBlank(dlData) && StringUtils.isNotBlank(layerName) && text.equals("[地理分析]")) {
                    //获取下标
                    XmlCursor cursor = paragraph.getCTP().newCursor();
                    XWPFTable table = document.insertNewTbl(cursor);
                    XWPFTableRow row_0 = table.getRow(0);
                    Class objectClass = null;
                    switch (layerName) {
                        case "村点":
                            objectClass = VillagePointLayer.class;
                            //json字符串转换为对象列表
                            List<VillagePointLayer> dlList = JSON.parseArray(ybData, objectClass);

                            //添加表头

                            row_0.getCell(0).setText("村名");
                            row_0.addNewTableCell().setText("村长");
                            row_0.addNewTableCell().setText("联系电话");
                            row_0.addNewTableCell().setText("人口数量");
                            //设置数据
                            dlList.forEach(dl -> {
                                System.out.println(dl);
                                XWPFTableRow dataRow = table.createRow();
                                dataRow.getCell(0).setText(dl.getNAME());

                            });
                            break;
                        case "乡镇面":
                            //添加表头
                            row_0.getCell(0).setText("乡镇名称");
                            row_0.addNewTableCell().setText("镇长");
                            row_0.addNewTableCell().setText("联系电话");
                            row_0.addNewTableCell().setText("人口数量");
                            break;
                    }

                    setTableLocation(table, "center");
                    setCellLocation(table, "CENTER", "center");
                    document.removeBodyElement(document.getPosOfParagraph(paragraph));
                }
            }

            templateStream.close();
            // 将生成的文档保存到输出文件
            document.write(targetSteam);
            log.info("文档生成成功");
            targetSteam.close();

            // 设置前端响应
            byte[] buffer = new byte[1024];
            int bytesRead;
            FileInputStream inputStream = new FileInputStream(targetPath);
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, bytesRead);
            }
            byte[] byteArray = byteArrayOutputStream.toByteArray();

            HttpHeaders headers = new HttpHeaders();
            headers.setContentDispositionFormData("attachment", "产品文档.docx");
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentLength(byteArray.length);
            return new ResponseEntity<>(byteArray, headers, HttpStatus.OK);

        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("文档生成失败");
        }
        return null;
    }

    private Object getLayerObject(List<DmRcoVal> rec, String layerName) throws NoSuchFieldException, InstantiationException, IllegalAccessException {
        Class objectClass = LayerUtil.getLayerClass(layerName);

        Object object = objectClass.newInstance();
        for (DmRcoVal dmRcoVal : rec) {
            Field field = objectClass.getDeclaredField(dmRcoVal.getFldName());//获取私有字段
            field.setAccessible(true);//设置权限
            if (dmRcoVal.getFldName().equals("NAME") && layerName.equals("乡村道路") && dmRcoVal.getFldVal().trim().length() == 0) {
                field.set(object, "无名道路");
            } else if (dmRcoVal.getFldName().equals("NAME")) {
                field.set(object, dmRcoVal.getFldVal().trim());
            } else {
                field.set(object, dmRcoVal.getFldVal());

            }
        }
        return object;
    }


    /**
     * 设置单元格水平位置和垂直位置
     *
     * @param xwpfTable
     * @param verticalLoction    单元格中内容垂直上TOP，下BOTTOM，居中CENTER，BOTH两端对齐
     * @param horizontalLocation 单元格中内容水平居中center,left居左，right居右，both两端对齐
     */
    public static void setCellLocation(XWPFTable xwpfTable, String verticalLoction, String horizontalLocation) {
        List<XWPFTableRow> rows = xwpfTable.getRows();
        for (XWPFTableRow row : rows) {
            List<XWPFTableCell> cells = row.getTableCells();
            for (XWPFTableCell cell : cells) {
                CTTc cttc = cell.getCTTc();
                CTP ctp = cttc.getPList().get(0);
                CTPPr ctppr = ctp.getPPr();
                if (ctppr == null) {
                    ctppr = ctp.addNewPPr();
                }
                CTJc ctjc = ctppr.getJc();
                if (ctjc == null) {
                    ctjc = ctppr.addNewJc();
                }
                ctjc.setVal(STJc.Enum.forString(horizontalLocation)); //水平居中
                cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.valueOf(verticalLoction));//垂直居中
            }
        }
    }

    /**
     * 设置表格位置
     *
     * @param xwpfTable
     * @param location  整个表格居中center,left居左，right居右，both两端对齐
     */
    public static void setTableLocation(XWPFTable xwpfTable, String location) {
        CTTbl cttbl = xwpfTable.getCTTbl();
        CTTblPr tblpr = cttbl.getTblPr() == null ? cttbl.addNewTblPr() : cttbl.getTblPr();
        CTJc cTJc = tblpr.addNewJc();
        cTJc.setVal(STJc.Enum.forString(location));
    }

    private static List<Dopxml> parseXMLdop(String xmlData) {
        List<Dopxml> locations = new ArrayList<>();
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(new InputSource(new StringReader(xmlData)));

            NodeList featureList = document.getElementsByTagName("FEATURE");
            for (int i = 0; i < featureList.getLength(); i++) {
                Element feature = (Element) featureList.item(i);
                Element fields = (Element) feature.getElementsByTagName("FIELDS").item(0);
                Element pos = (Element) feature.getElementsByTagName("POS").item(0);

                Dopxml dopxml = new Dopxml();
                dopxml.setDmgisId(fields.getAttribute("dmgis_id"));
                dopxml.setName(fields.getAttribute("名称"));
                dopxml.setType(pos.getAttribute("type"));
                dopxml.setPnt(pos.getAttribute("pnt"));
                locations.add(dopxml);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return locations;
    }

    private static List<Location> parseXMLArea(String xmlData) {
        List<Location> locations = new ArrayList<>();
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(new InputSource(new StringReader(xmlData)));

            NodeList featureList = document.getElementsByTagName("FEATURE");
            for (int i = 0; i < featureList.getLength(); i++) {
                Element feature = (Element) featureList.item(i);
                Element fields = (Element) feature.getElementsByTagName("FIELDS").item(0);

                Location location = new Location();
                location.setDmgisId(fields.getAttribute("dmgis_id"));
                location.setObjectId(fields.getAttribute("OBJECTID"));
                location.setElemId(fields.getAttribute("ELEMID"));
                location.setName(fields.getAttribute("NAME"));
                location.setPac(fields.getAttribute("PAC"));
                location.setProDate(fields.getAttribute("PRODATE"));
                location.setSource(fields.getAttribute("SOURCE"));
                location.setPrctag(fields.getAttribute("PRCTAG"));
                location.setCc(fields.getAttribute("CC"));
                location.setAscription(fields.getAttribute("ASCRIPTION"));
                location.setEname(fields.getAttribute("ENAME"));
                location.setChangeAtt(fields.getAttribute("CHANGEATT"));
                location.setShapeLeng(fields.getAttribute("Shape_Leng"));
                location.setShapeArea(fields.getAttribute("Shape_Area"));
                location.setCounty(fields.getAttribute("所属县"));

                locations.add(location);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return locations;
    }

}







